#include <dbus/dbus.h>

#include <stdio.h>

DBusError err;
DBusConnection *conn;

DBusMessage *msg_Audio_PushScenario, *msg_Audio_PullScenario, *msg_IdleNotifier_SetState;

int
udbus_init() {
  fprintf(stdout, "Initialize dbus connection..\n");
  // initialise the errors
  dbus_error_init(&err);
  // connect to the bus
  conn = dbus_bus_get(DBUS_BUS_SYSTEM, &err);
  if (dbus_error_is_set(&err)) { 
    fprintf(stderr, "Connection Error (%s)\n", err.message); 
    dbus_error_free(&err);
  }
  
  if (NULL == conn) { 
    return 0;
  }
  
  msg_Audio_PushScenario = dbus_message_new_method_call("org.freesmartphone.odeviced",
							"/org/freesmartphone/Device/Audio",
							"org.freesmartphone.Device.Audio",
							"PushScenario");
  if (NULL == msg_Audio_PushScenario) {
    fprintf(stderr, "Message Null\n");
  }
  
  msg_Audio_PullScenario = dbus_message_new_method_call("org.freesmartphone.odeviced",
							"/org/freesmartphone/Device/Audio",
							"org.freesmartphone.Device.Audio",
							"PullScenario");
  if (NULL == msg_Audio_PullScenario) {
    fprintf(stderr, "Message Null\n");
  }
  
  msg_IdleNotifier_SetState = dbus_message_new_method_call("org.freesmartphone.odeviced",
							   "/org/freesmartphone/Device/IdleNotifier/0",
							   "org.freesmartphone.Device.IdleNotifier",
							   "SetState");
  if (NULL == msg_IdleNotifier_SetState) {
    fprintf(stderr, "Message Null\n");
  }
  
}

void
udbus_finalize() {
  fprintf(stdout, "Finalize dbus connection..\n");
  // free message
  dbus_message_unref(msg_Audio_PushScenario);
  dbus_message_unref(msg_Audio_PullScenario);
  dbus_message_unref(msg_IdleNotifier_SetState);
  
  dbus_connection_close(conn);
}

int
audio_push_scenario(const char* scenario) {
  DBusMessageIter args;
  DBusPendingCall *pending;
  
  fprintf(stdout, "Push audio scenario \"%s\"..\n", scenario);
  
  // append arguments
  dbus_message_iter_init_append(msg_Audio_PushScenario, &args);
  if (!dbus_message_iter_append_basic(&args, DBUS_TYPE_STRING, &scenario)) { 
    fprintf(stderr, "Out Of Memory!\n");
    return 0;
  }
  
  // send message and get a handle for a reply
  if(!dbus_connection_send_with_reply(conn, msg_Audio_PushScenario, &pending, -1)) {
    fprintf(stderr, "Out Of Memory!\n");
    return 0;
  }
  if(NULL == pending) { 
    fprintf(stderr, "Pending Call Null\n"); 
    return 0;
  }
  
  dbus_connection_flush(conn);
}

int
audio_pull_scenario() {
  DBusPendingCall *pending;
  
  fprintf(stdout, "Pull audio scenario..\n");
  
  // send message and get a handle for a reply
  if (!dbus_connection_send_with_reply(conn, msg_Audio_PullScenario, &pending, -1)) { 
    // -1 is default timeout
    fprintf(stderr, "Out Of Memory!\n"); 
    return 0;
  }
  if (NULL == pending) {
    fprintf(stderr, "Pending Call Null\n"); 
    return 0;
  }
  dbus_connection_flush(conn);
}

int
idle_notifier_set_state(const char* state) {
  DBusMessageIter args;
  DBusPendingCall *pending;
  
  fprintf(stdout, "Idle notifier set state..\n");
  
  // append arguments
  dbus_message_iter_init_append(msg_IdleNotifier_SetState, &args);
  if (!dbus_message_iter_append_basic(&args, DBUS_TYPE_STRING, &state)) { 
    fprintf(stderr, "Out Of Memory!\n"); 
    return 0;
  }
  
  // send message and get a handle for a reply
  if(!dbus_connection_send_with_reply(conn, msg_IdleNotifier_SetState, &pending, -1)) {
    fprintf(stderr, "Out Of Memory!\n"); 
    return 0;
  }
  if(NULL == pending) { 
    fprintf(stderr, "Pending Call Null\n"); 
    return 0;
  }
  
  dbus_connection_flush(conn);
}
